<?php

/**
 * @Author: king
 * @Date:   2019-05-05 19:58:37
 * @Last Modified by:   king
 * @Last Modified time: 2019-06-06 23:13:33
 */

namespace App\Http\Controllers\Api\v3;

use App\Http\Controllers\Api\BaseController;
use App\Http\Controllers\Api\v1\Order\OrdersPayController;
use App\Http\Controllers\Api\v2\DivinationController as DivinationControllerIndex;
use App\Models\Api\LanmeiCounselor;
use App\Models\Api\LanmeiCounselorAnswer;
use App\Models\Api\LanmeiCounselorAnswerOnlooker;
use App\Models\Api\LanmeiCounselorGrabRecord;
use App\Models\Api\LanmeiCounselorProblem;
use App\Models\Api\LanmeiCounselorProblemPrice;
use App\Models\Api\LanmeiCounselorProblemRecode;
use App\Models\Api\LanmeiTag;
use App\Models\Api\LanmeiUserAccount;
use App\Models\Api\LanmeiUserCounselorStatus;
use App\Tools\ProblemAndAnswerJob;
use App\Tools\Validates\CounselorProblem;
use App\Tools\Validates\LanmeiAnswerComment;
use Illuminate\Http\Request;

class QuestionsController extends BaseController
{
    protected $model = null;

    public function test()
    {

        // CacheManage::getInstance()->setCacheConfig()
        //     ->setCache();

        // $queueConfig = config('queue');
        // queuePush($queueConfig['problem_refund_task'], ['refund_id' => '05201905311606058081001'], $queueConfig['problem_refund_queue'], $queueConfig['problem_refund_delay']);
        die;
        // $queueConfig = config('queue');
        // queuePush($queueConfig['problem_padding_task'], ['cp_id' => 610], $queueConfig['problem_padding_queue'], 2);
        // echo 1;
    }

    /**
     * 问答广场
     * @throws \Exception
     */
    public function index()
    {
        $uid = $request->uid;

        $counselotProblemModel = (new LanmeiCounselorProblem());

        $problemData = $counselotProblemModel->getProblemIndex();

        $orderNum = $counselotProblemModel->getOrderTotalNum();

        // 获取用户身份 是否是咨询师
        $counselorStatus = (new LanmeiUserCounselorStatus())->getUserCounselorStatus($uid);

        // 判断用户占星师身份时；是否还有抢答次数
        if ($counselorStatus && $counselorStatus['status'] > 0)
        {
            // 获取咨询师今天抢答未完成的次数
            $unfinishedNum = LanmeiCounselorGrabRecord::getUserGrabUnfinishNumByDay($counselorStatus['c_id']);

            $isGrab = $unfinishedNum < 3 ? 1 : 0;
        } else
        {
            $isGrab = 0;
        }

        $res = [
            'stargazer_people' => $orderNum['sta'],
            'divination_people' => $orderNum['div'],
            'is_grab' => $isGrab,
            'data' => $problemData
        ];

        return show(config('code.success'), '请求成功', $res);
    }

    /**
     * 问答广场 更多
     * @return \response\Json
     * @throws \exception\ApiException
     */
    public function lists(Request $request)
    {
        $param['type'] = $request->input('type', 0);
        $param['cid'] = $request->input('cid', 0);
        $param['status'] = $request->input('status', 0);

        $data = (new LanmeiCounselorProblem())->getProblemList($param);

        return show(config('code.success'), '请求成功', $data);
    }

    /**
     * 获取围观价格
     */
    public function getReadPrice()
    {
        $priceData = [
            'price' => $this->readPrice()
        ];

        return show(config('code.success'), '请求成功', $priceData);
    }

    /**
     * 获取围观价格
     * @return string
     */
    protected function readPrice()
    {
        return '1.00';
    }

    /**
     * 获取公开悬赏价格
     * @return \response\Json
     * @throws \Exception
     */
    public function getOpenedPrice(Request $request)
    {
        $type = $request->input('type', 0);
        if (!in_array($type, [1, 2]))
        {
            return show(config('code.error'), '问题类型异常');
        }

        $priceData = (new LanmeiCounselorProblemPrice())->getOpenedPrice($type);
        // 数组数据去除键名
        $priceData = array_values($priceData);

        return show(config('code.success'), '请求成功', ['data' => $priceData]);
    }

    /**
     * 创建咨询问题
     * @return \response\Json
     * @throws \exception\ApiException
     * @throws \Exception
     */
    public function create(Request $request)
    {
        $type = $request->input('type', 0);
        $tagId = $request->input('tag_id', 0);
        $timezone = $request->input('timezone', 0);
        $title = $request->input('title', '');
        $rids = explode(',', $request->input('rid', ''));
        $lng = $request->input('lng', '');
        $lat = $request->input('lat', '');

        $problemData = [
            'tag_id' => $tagId,
            'title' => $title,
        ];
        // 数据校验
        $validate = new CounselorProblem();
        if (!$validate->check($problemData))
        {
            return show(config('code.error'), $validate->getError());
        }

        switch ($type)
        {
            case 1:
                // 占星
                $ids = (new LanmeiCounselorProblemRecode())->copeRecode($rids);

                $problemData['bind_id'] = implode(',', $ids);
                break;
            case 2:
                // 占卜
                $map = [
                    'tag_id' => $tagId, //标签类型
                    'question' => $title, //问题内容
                    'timezone' => $timezone, //时区
                    'longitude' => $lng, //经度
                    'latitude' => $lat, //维度
                    'uid' => $request->uid
                ];
                $divinationId = (new DivinationControllerIndex())->get($map);

                $problemData['bind_id'] = $divinationId;
                break;
            default:
                return show(config('code.error'), '请求异常');
        }

        // 去创建问题
        $problemData['problem_type'] = $type; //问题类型
        $problemData['problem_status'] = 1; //状态 待提交
        $problemData['uid'] = $request->uid; //
        $problemData['create_time'] = time(); //当前时间戳

        $problemModel = new LanmeiCounselorProblem();
        $cpId = $problemModel->insertProblemData($problemData);
        // 添加缓存 用户提问ID
        $problemModel->addUserProblemID($problemData['uid'], $cpId);

        return show(config('code.success'), '请求成功', ['cp_id' => $cpId]);
    }

    /**
     * 获取创建问题详情
     * @return \response\Json
     * @throws \Exception
     */
    public function getCreateInfo(Request $request)
    {
        $cpId = $request->input('cp_id', 0);
        if ($cpId === 0)
        {
            return show(config('code.error'), '提问不存在');
        }

        $problemData = (new LanmeiCounselorProblem())->getProblemInfoById($cpId, 'id,problem_type,tag_id,title,bind_id,create_time');

        if (!$problemData)
        {
            return show(config('code.error'), '提问不存在');
        }

        $returnData = [
            'cp_id' => $problemData['id'],
            'type' => $problemData['problem_type'],
            'title' => $problemData['title'],
            'time' => date('Y-m-d H:i', $problemData['create_time'])
        ];

        switch ($returnData['type'])
        {
            case 1:
                // 占星
                $returnData['record_info'] = (new LanmeiCounselorProblemRecode())->getCreateProblemRecode($problemData['bind_id']);
                break;
            case 2:
                // 占卜
                $returnData['divination_info'] = (new DivinationControllerIndex())->dice(['did' => $problemData['bind_id']]);
                break;
            default:
                return show(config('code.error'), '服务异常');
        }

        $returnData['tag_id'] = $problemData['tag_id'];
        $returnData['tag_name'] = LanmeiTag::getTagNameById(1, $problemData['tag_id']);

        return show(config('code.success'), '请求成功', $returnData);
    }

    /**
     * 问题下单并去支付
     * @return \response\Json
     * @throws \exception\ApiException
     * @throws \Exception
     * @throws \Exception
     * @throws \db\exception\DataNotFoundException
     * @throws \db\exception\ModelNotFoundException
     * @throws \exception\DbException
     */
    public function problemPay(Request $request)
    {
        $params = [];
        $params['cp_id'] = $request->input('cp_id', 0);
        $params['is_opened'] = $request->input('is_opened');
        $params['type'] = $request->input('type'); //悬赏类型 1指定 2公开
        $params['counselor_ids'] = $request->input('counselor_ids', '');
        $params['gid'] = $request->input('gid', 0);
        $params['trade_type'] = $request->input('trade_type', 0);
        $params['openid'] = $request->input('openid', '');
        $params['callback_url'] = $request->input('callback_url', '');

        // 参数校验---------------
        $validateResult = $this->problemPayParamValidate($params);
        if ($validateResult['status'] === false)
        {
            return show(config('code.error'), $validateResult['msg']);
        }
        // 咨询问题信息并做 状态校验--------------
        $problemInfo = (new LanmeiCounselorProblem)->getProblemInfoById($params['cp_id'], 'problem_status,problem_type,order_id');
        if (!$problemInfo)
        {
            return show(config('code.error'), '问题不存在');
        }
        // 获取问题状态
        $problemStatus = $problemInfo['problem_status'];
        // 获取悬赏问题类型
        $problemType = $problemInfo['problem_type'];
        //判断问题类型,获取订单类型 8占星 7占卜
        $cp_type = $problemType == 1 ? 8 : 7;

        if (!in_array($problemStatus, [1, 2]))
        {
            return show(config('code.error'), '已经支付过了');
        }
        // 已经下过单 关闭旧订单
        if ($problemStatus == 2)
        {
            (new \App\Models\Api\Orders())->where(['order_id' => $problemInfo['order_id']])->update(['status' => 2]);
        }
        // 获取咨询价格------------
        if ($params['type'] == 1)
        {
            // 指定悬赏
            // 获取咨询价格
            $counselorsPriceData = (new LanmeiCounselor())->getCounselorsPrice($params['counselor_ids'], $problemType);
            // 下单数据组合
            $orderData = [
                'order_type' => $cp_type,
                'trade_type' => $params['trade_type'],
                'gid' => $params['cp_id'],
                'openid' => $params['openid'],
                'callback_url' => $params['callback_url'],
                'extend' => [ // 问题数据更新
                    'id' => $params['cp_id'],
                    'is_opened' => $params['is_opened'],
                    'people' => $counselorsPriceData['people'],
                    'counselor_price' => $counselorsPriceData['totalPrice'],
                    'problem_status' => 2,
                    'extend' => json_encode(['counselor_info' => $counselorsPriceData['counselorPrices']]),
                    'counselor_ids' => $params['counselor_ids'],
                    'counselor_mode' => 1,
                ]
            ];
        } else
        {
            // 公开悬赏
            $problemPriceData = (new LanmeiCounselorProblemPrice())->getProblemOpenedPrice($params['gid'], $problemType);
            if (empty($problemPriceData))
            {
                return show(config('code.error'), '悬赏人数异常');
            }
            // 下单数据组合
            $orderData = [
                'order_type' => $cp_type,
                'trade_type' => $params['trade_type'],
                'gid' => $params['cp_id'],
                'openid' => $params['openid'],
                'callback_url' => $params['callback_url'],
                'extend' => [ // 问题数据更新
                    'id' => $params['cp_id'],
                    'is_opened' => $params['is_opened'],
                    'people' => $problemPriceData['people'],
                    'counselor_price' => $problemPriceData['price'],
                    'problem_status' => 2,
                    'extend' => '',
                    'counselor_ids' => $params['counselor_ids'],
                    'counselor_mode' => 2,
                ]
            ];
        }
        // 去下单 -----------
        $resultData = (new OrdersPayController())->pay_unlock($orderData);

        if ($resultData['status'] === true)
        {
            return show(config('code.success'), '下单成功', $resultData['data']);
        } else
        {
            return show(config('code.error'), '下单失败', $resultData['data']);
        }
    }

    /**
     * 支付参数校验
     * @param $params
     * @return array
     */
    protected function problemPayParamValidate($params)
    {
        if ($params['cp_id'] === 0)
        {
            return ['status' => false, 'msg' => '提问不存在'];
        }

        if (!in_array($params['is_opened'], [0, 1]) || !in_array($params['type'], [1, 2]))
        {
            return ['status' => false, 'msg' => '参数异常'];
        }

        if ($params['type'] == 1)
        {
            if (empty($params['counselor_ids']))
            {
                return ['status' => false, 'msg' => '请选择咨询师'];
            }
        } else
        {
            if ($params['gid'] === 0 || !$params['gid'])
            {
                return ['status' => false, 'msg' => '请选择悬赏人数'];
            }
        }

        if (!in_array($params['trade_type'], [1, 2, 5, 6, 7, 8]))
        {
            return ['status' => false, 'msg' => '支付方式错误'];
        }

        if (in_array($params['trade_type'], [7, 8]) && empty($params['callback_url']))
        {
            return ['status' => false, 'msg' => '回调异常'];
        }

        if ($params['trade_type'] == 6 && empty($params['openid']))
        {
            return ['status' => false, 'msg' => 'openid不能为空'];
        }

        return ['status' => true, 'msg' => ''];
    }

    /**
     * 获取问题详情
     * @return \response\Json
     * @throws \exception\ApiException
     * @throws \db\exception\DataNotFoundException
     * @throws \db\exception\ModelNotFoundException
     * @throws \exception\DbException
     */
    public function info(Request $request)
    {
        $cpId = $request->input('cp_id', 0);
        $isGrab = $request->input('is_grab', 0);

        if ($cpId === 0)
        {
            return show(config('code.error'), '提问不存在');
        }
        $uid = $request->uid;
        // 通过问题ID获取问题详情
        $problemMpdel = new LanmeiCounselorProblem();
        // 获取问题详情
          $problemInfo = $problemMpdel->getProblemInfoById($cpId, 'id,create_time,update_time,tag_id,title,is_opened,problem_type,counselor_mode,people,counselor_ids,answer_people,counselor_price,problem_status,bind_id,uid,accept_answer,answer_ids');
        $caIds = explode(',', $problemInfo['answer_ids']);

        $timeName = in_array($problemInfo['problem_status'], [1, 2]) ? 'create_time' : 'update_time';

        $resultData = [
            'cp_id' => $problemInfo['id'],
            'type' => $problemInfo['problem_type'], //咨询类型
            'title' => $problemInfo['title'], //咨询问题
            'tag_name' => LanmeiTag::getTagNameById(1, $problemInfo['tag_id']), //咨询类型 爱情/事业
            'time' => date('Y-m-d H:i', $problemInfo[$timeName]),
            'is_opened' => (int)$problemInfo['is_opened'], //能否围观
            'is_answer' => 0, // 默认不能回答
            'people' => $problemInfo['people'],
            'answer_people' => $problemInfo['answer_people'],
            'price' => $problemInfo['counselor_price'],
            'accept_answer' => $problemInfo['accept_answer'],
        ];
        $resultData = array_merge($resultData, $problemMpdel->getBindData($problemInfo['bind_id'], $problemInfo['problem_type']));

        // 判断是不是本人查看
        if ($problemInfo['uid'] == $request->uid)
        { //是
            switch (true)
            {
                case in_array($problemInfo['problem_status'], [1, 2]):
                    // 去支付/待支付
                    // 获取用户账号信息
                    $userAccountInfo = (new LanmeiUserAccount())->getAccountInfoAndCreate($uid);
                    $resultData['balance'] = $userAccountInfo['status'] == 1 ? $userAccountInfo['balance'] : '0.00';
                    $resultData['status'] = 1;
                    if ($problemInfo['counselor_mode'] == 2)
                    { //公开悬赏
                        $resultData['opened_price'] = array_values((new LanmeiCounselorProblemPrice())->getOpenedPrice($problemInfo['problem_type']));
                    } else
                    { //指定悬赏
                        $counselorsPriceData = (new LanmeiCounselor())->getCounselorsPrice($problemInfo['counselor_ids'], $resultData['type']);
                        // 之前选择的咨询师信息
                        foreach ($counselorsPriceData['counselorPrices'] as $counselorPriceItem)
                        {
                            $resultData['conselor_info'][] = [
                                'cid' => $counselorPriceItem['id'],
                                'cname' => $counselorPriceItem['nickname'],
                                'price' => $counselorPriceItem['price'],
                            ];
                        }
                    }
                    break;
                case in_array($problemInfo['problem_status'], [3, 4, 5]):
                    $resultData['is_me'] = 1;
                    // [3,4]待咨询师回答/待结算 5已完成
                    $resultData['status'] = $problemInfo['problem_status'];
                    // 获取答案信息
                    $answerData = (new LanmeiCounselorAnswer())->getAnswerByCpid($caIds);

                    $resultData['answer_list'] = $answerData['info'];
                    break;
                default: //失效
                    $resultData['status'] = 5;
            }
        } else
        { //不是
            $resultData['is_me'] = 0;
            switch (true)
            {
                case in_array($problemInfo['problem_status'], [1, 2]):
                    // 去支付/待支付
                    return show(config('code.error'), '问题不存在');
                    break;
                case in_array($problemInfo['problem_status'], [3, 4, 5]):
                    // 3 待回复   4 待结算  5 已完成
                    $resultData['status'] = $problemInfo['problem_status'];
                    // 获取答案信息
                    $answerData = (new LanmeiCounselorAnswer())->getAnswerByCpid($cpId);
                    // 获取用户身份信息 是否是该问题类型的咨询师 return true/false
                    $userCounselorStatus = (new LanmeiUserCounselorStatus())->getUserCounselorStatus($uid);
                    $isProblemCounselor = ($userCounselorStatus && $userCounselorStatus['counselor_status'] == 1 && in_array($userCounselorStatus['status'], [3, $resultData['type']])) ? 1 : 0; // 用户是不是该问题的咨询师
                    $userCid = $userCounselorStatus['c_id'] ?? 0;
                    // 获取答案信息
                   // $answerData = (new LanmeiCounselorAnswer())->getAnswerByCpid($caIds, $userCid);
                    // 待回答状态 用户是不是咨询师，并且之前没有回答,并且还有剩余回答的机会,或者是抢答的情况
                    if ($problemInfo['problem_status'] == 3 // 待回答状态
                        && $isProblemCounselor // 用户是该问题的咨询师
                        && ($problemInfo['counselor_mode'] == 1 // 判断是不是指定回答
                            ? in_array($userCounselorStatus['c_id'], $answerData['cids']) // 是 答案里面有当前咨询师的待回答数据
                            : !in_array($userCounselorStatus['c_id'], $answerData['cids']) // 不是 用户没有回答过该题目
                        )
                        && ($resultData['answer_people'] < $resultData['people'] || $isGrab == 1)) // 还有没有答题机会 或者当前问题是抢答
                    {
                        $resultData['is_answer'] = 1; //用户可以回复
                        break;
                    }
                    // 获取当前用户所有围观的答案ID
                    $answerOnlookerIds = (new LanmeiCounselorAnswerOnlooker())->getUserReadAnswerIds($uid);

                    // 组合答案信息
                    $resultData['answer_list'] = [];
                    foreach ($answerData['info'] as $answerItem)
                    {
                        $isSelf = $answerItem['c_id'] == $userCid ? 1 : 0;
                        $resultData['answer_list'][] = [
                            'c_id' => $answerItem['c_id'],
                            'avatar' => $answerItem['avatar'],
                            'nickname' => $answerItem['nickname'],
                            'time' => $answerItem['time'],
                            'type' => $answerItem['type'],
                            // 判断答案是否围观过了
                            'content' => ($isSelf || in_array($answerItem['ca_id'], $answerOnlookerIds)) ? $answerItem['content'] : '',
                            'ca_id' => $answerItem['ca_id'],
                            'is_comment' => $answerItem['is_comment'],
                            'duration' => $answerItem['duration'],
                            'state' => $answerItem['state'],
                            'read_num' => $answerItem['read_num'],
                            'my_answer' => $isSelf
                        ];
                    }
                    break;
                default: //失效
                    return show(config('code.error'), '问题不存在');
            }
        }

        return show(config('code.success'), '请求成功', $resultData);
    }

    /**
     * 答案采纳
     * @throws \Exception
     */
    public function answerAccept(Request $request)
    {
        $caId = $request->input('ca_id', 0);
        if ($caId === 0)
        {
            return show(config('code.error'), '答案不存在');
        }
        // 答案采纳
        (new LanmeiCounselorAnswer())->accept($caId, $request->uid);

        return show(config('code.success'), '采纳成功');
    }

    /**
     * 答案举报
     * @return \response\Json
     * @throws \Exception
     */
    public function answerInform(Request $request)
    {
        $caId = $request->input('ca_id', 0);
        $content = $request->input('content', '');
        $tid = $request->input('tid', '');
        if ($caId === 0)
        {
            return show(config('code.error'), '答案不存在');
        }
        if (empty($tid))
        {
            return show(config('code.error'), '请选择举报原因');
        }

        $len = mb_strlen($content);
        if ($len > 30)
        {
            return show(config('code.error'), '举报内容在30字内');
        }
        // 去举报
        (new LanmeiCounselorAnswer())->answerInform($caId, $tid, $content, $request->uid);

        return show(config('code.success'), '举报成功');
    }

    /**
     * 答案评价
     * @return \response\Json
     * @throws \exception\ApiException
     */
    public function toComment(Request $request)
    {
        $params['id'] = $request->input('id', 0);
        $params['ca_id'] = $request->input('ca_id', 0);
        $params['grade'] = $request->input('grade', 0);
        $params['tag_ids'] = explode(',', $request->input('tag_ids', ''));
        $params['content'] = $request->input('content', '');
        // 参数校验---------------
        $valdateModel = new LanmeiAnswerComment();

        if (!$valdateModel->check($params))
        {
            return show(config('code.error'), $valdateModel->getError());
        }

        (new LanmeiCounselorAnswer())->answerToComment($params, $request->uid);

        return show(config('code.success'), '评价成功');
    }

    /**
     * 获取评价详情
     * @return \response\Json
     * @throws \exception\ApiException
     * @throws \Exception
     */
    public function getCommentInfo(Request $request)
    {
        $caId = $request->input('ca_id', 0);
        if ($caId === 0)
        {
            return show(config('code.error'), '答案不存在');
        }

        $commentData['comment'] = LanmeiCounselorAnswer::getCommentInfo($caId);
        $commentData['inform'] = LanmeiCounselorInform::getInformInfo($caId);

        return show(config('code.success'), '请求成功', $commentData);
    }

    /**
     * 问题围观
     * @return \response\Json
     * @throws \XznsTools\exception\ApiException
     * @throws \exception\ApiException
     * @throws \db\exception\DataNotFoundException
     * @throws \db\exception\ModelNotFoundException
     * @throws \exception\DbException
     */
    public function answerRead(Request $request)
    {
        $caId = $request->input('ca_id', 0);
        $tradeType = $request->input('trade_type', 0);
        $openId = $request->input('openid', '');
        $callbackUrl = $request->input('callback_url', '');

        if (!in_array($tradeType, [1, 2, 5, 6, 7, 8]))
        {
            return show(config('code.error'), '支付方式异常');
        }

        if ($caId === 0)
        {
            return show(config('code.error'), '答案不存在');
        }
        // 获取用户围观过的 答案ID
        $readData = (new LanmeiCounselorAnswerOnlooker())->getUserReadAnswerIds($request->uid);
        if (in_array($caId, $readData))
        {
            return show(config('code.error'), '答案已经围观过了');
        }

        $orderData = [
            'order_type' => 9, // 平台围观
            'trade_type' => $tradeType,
            'gid' => $caId,
            'openid' => $openId,
            'callback_url' => $callbackUrl,
            'extend' => [
                'price' => $this->readPrice()
            ]
        ];

        // 去下单 -----------
        $resultData = (new OrdersPayController())->pay_unlock($orderData);

        if ($resultData['status'] === true)
        {
            return show(config('code.success'), '下单成功', $resultData['data']);
        } else
        {
            return show(config('code.error'), '下单失败', $resultData['data']);
        }
    }


    /**
     * 我的提问接口
     * @return \response\Json
     * @throws \Exception
     */
    public function getMyQuestion(Request $request)
    {
        $page = $request->input('page', 1);

        $uid = $request->uid;

        $ProblemModel = new LanmeiCounselorProblem();

        $data = $ProblemModel->getMyProblemList($uid, $page);

        return show(config('code.success'), '获取成功', $data);
    }

    /**
     * 我的提问删除接口
     * @return \response\Json
     * @throws \Exception
     */
    public function delMyQuestion(Request $request)
    {
        $param = $request->only(['cp_id']);
        $ProblemModel = new LanmeiCounselorProblem();
        $data = $ProblemModel->getProblemInfoById($param, 'id');
        if ($data)
        {
            $res = $ProblemModel->problemUpdate(['id' => $param['cp_id'], ['delete_time' => time()]]);

            if ($res === false)
            {
                return show(config('code.error'), $ProblemModel->getError());
            }

            return show(config('code.success'), '操作成功');
        } else
        {
            return show(config('code.success'), '问题不存在');
        }

    }
}
